#!/usr/bin/env python
# coding: utf-8 

import sys
import tempfile
import math
from optparse import OptionParser
from xml.dom import minidom as dom
from subprocess import Popen,PIPE
import subprocess
from decimal import Decimal
from numbers import Number
import time
import os
from os.path import basename
import signal
import pprint

SCRIPT_DIR = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))

def create_gnuplot_histogram_file(dataFile, field, legend, xlabel, ylabel):

    name = 'histogram-'+field
    histogramFile = 'histogram-'+field + ".pdf"
    plotFile = 'histogram-'+field + ".plot"

    colors = []
    colors.append(('21',"#a40000")) # Scarlet Red 3
    colors.append(('22',"#4e9a06")) # Chameleon 3
    colors.append(('23',"#5c3566")) # Plum 3
    colors.append(('24',"#204a87")) # Sky Blue 3
    colors.append(('25',"#ce5c00")) # Orange 3
    colors.append(('27',"#c4a000")) # Butter 3
    colors.append(('26',"#8f5902")) # Chocolate 3
    colors.append(('28',"#2e3436")) # Aluminium 6
    colors.append(('11',"#a40000")) # Scarlet Red 3
    colors.append(('12',"#4e9a06")) # Chameleon 3
    colors.append(('13',"#5c3566")) # Plum 3
    colors.append(('14',"#204a87")) # Sky Blue 3
    colors.append(('17',"#c4a000")) # Butter 3
    colors.append(('16',"#8f5902")) # Chocolate 3
    colors.append(('18',"#2e3436")) # Aluminium 6

    template = """
#set title "hohoho" 
set grid
#set size ratio 0.4
# Line style for axes
set style line 80 lt rgb "#808080"

# Line style for grid
set style line 81 lt 0  # dashed
set style line 81 lt rgb "#808080"  # grey

set grid back linestyle 81

set border 3 back linestyle 80 # Remove border on top and right.  These
#Remove as linhas superior e direta
set xtics nomirror
set ytics nomirror

#Definie estilos de cor com cores Tango

set style line 21 lt rgb "#cc0000" # Scarlet Red 2
set style line 22 lt rgb "#73d216" # Chameleon 2
set style line 23 lt rgb "#75507b" # Plum 2
set style line 24 lt rgb "#3465a4" # Sky Blue 2
set style line 25 lt rgb "#f57900" # Orange 2
set style line 26 lt rgb "#c17d11" # Chocolate 2
set style line 27 lt rgb "#edd400" # Butter 2
set style line 28 lt rgb "#d3d7cf" # Aluminium 2

set style line 31 lt rgb "#a40000" # Scarlet Red 3
set style line 32 lt rgb "#4e9a06" # Chameleon 3
set style line 33 lt rgb "#5c3566" # Plum 3
set style line 34 lt rgb "#204a87" # Sky Blue 3
set style line 35 lt rgb "#ce5c00" # Orange 3
set style line 36 lt rgb "#8f5902" # Chocolate 3
set style line 37 lt rgb "#c4a000" # Butter 3
set style line 38 lt rgb "#2e3436" # Aluminium 6

set style line 11 lt rgb "#ef2929" # Scarlet Red 1
set style line 12 lt rgb "#8ae234" # Chameleon 1
set style line 13 lt rgb "#ad7fa8" # Plum 1
set style line 14 lt rgb "#729fcf" # Sky Blue 1
set style line 15 lt rgb "#babdb6" # Aluminium 3
set style line 16 lt rgb "#e9b96e" # Chocolate 1
set style line 17 lt rgb "#fce94f" # Butter 1
set style line 18 lt rgb "#eeeeec" # Aluminium 1

#set yrange [0:500]
#set xrange [5:]
#set ytics 100 
#set xtics 500 
#set xtics -1 
#set grid noxtics
#set mxtics 2
#set pointsize 0.8
#set size ratio 0.4  
#
#

#set key box ls 15
set key outside  top left horizontal 
set key textcolor rgb "#2e3436" 
#set key title "s"
set xlabel "%s"
set ylabel "%s"

set style data histogram
set style histogram cluster gap 1
set style fill solid border -1
set boxwidth 0.9

set terminal pdfcairo linewidth 3 rounded font ",6" color enhanced
set output "%s"

""" % (xlabel,ylabel,histogramFile)

    for i,report in enumerate(reports):
        f = "plot '" + dataFile +"'" if i == 0 else "     ''" + ' '*len(dataFile)
        h = '2:xtic(1)' if i == 0 else str(i+2)+' '*8
        c1 = colors[i][0] 
        c2 = colors[i][1]
         
        template += """%s using %s ti col ls %s fill solid border rgb "%s" """ % (f,h,c1,c2)
        if i<len(reports)-1:
            template += ", \\\n"

    f = open(OUTDIR+RESDIR+plotFile,"w+t")
    f.write(template)
    f.close()
    print "Gnuplot Script field '%s' writed to '%s'." % (field,f.name)
    Popen(["gnuplot",plotFile],cwd=OUTDIR+RESDIR).wait()
    return RESDIR+histogramFile 

def bold(text):
    return "$\\mathbf{%s}$" % text

def number(text):
    return "$%s$" % text

#Retorna o nome de um arquivo com dados para
#gnuplot gerar um histograma
def create_histrogram_data(field, keyField = 'instance'):
    temp = ""

    #Criando cabeçalhos de dados
    temp += COLS[keyField]['caption'] + ' '
    for report in reports:
        temp += report['id'] + ' '
    temp += '\n'

    #Preenchendo os dados
    for i in range(len(reports[0]['data'])):
        temp += reports[0]['data'][i][keyField] + ' '
        for report in reports:
            temp += str(report['data'][i][field]) + ' '
        temp += '\n'

    f = tempfile.NamedTemporaryFile(mode="w+t",delete=False)
    f.write(temp) 
    print "Report Data field '%s' writed to '%s'." % (field,f.name)
    return f.name

def create_histrogram_graf(field):
    temp = ""
    if COLS[field]['type'] != 'str':
        dataFile = create_histrogram_data(field,'instance')
        histogramFile = create_gnuplot_histogram_file(dataFile, field, "Comparison of field '%s'" % field, COLS['instance']['caption'], COLS[field]['caption'])
        temp += "\\begin{figure}\n" 
        temp += " \\caption{Comparison of %s}\n" % COLS[field]['caption'].lower()                  
        temp += " \\label{fig:%s-%s}\n" % (TESTID,"comparativo-"+field)                  
        temp += " \\centering\n"
        temp += " \\includegraphics[width=0.85\\textwidth]{%s}\n " % histogramFile
        #temp += " \\fbox{\\includegraphics{%s}}\n " % histogramFile
        #temp += " \\labelcaption{fig:%s-%s}{Gráfico comparativo do %s}\n" % (TESTID,"comparativo-"+field,COLS[field]['caption'].lower())
        temp += "\\end{figure}\n\n"
    return temp 

#Cria uma tabela com dados de vários relatórios 
def create_side_table2(description):
    t = "\\begin{table*}"
    t += "\\caption{%s}\n" % description                  
    t += "\\medskip\n"
    t += "\\label{tab:%s-%s}\n" % (TESTID,"sidetable")                  
    t += "\\centering\n"
    t += "\\tiny" + "\n"

    #Ajuste do alinhamento
    t += "\\begin{tabular}{@{}r"
    for r,row in enumerate(reports[0]['data']):
        t+= "@{}c@{}" #fake column
        for i in sideindex:
            t += ("r" if TYPES[i] in ("int","float") else "c") 
            if i != sideindex[-1]:
               t += "@{\\ \\ }" #Espaçamento entre colunas
            if i == sideindex[-1] and r == len(reports[0]['data'])-1:
               t += "@{}"
    t += "}\n"
    t += "\\hline\\noalign{\\smallskip}\n"

    #Captions of group
    t+= "& "
    for r,row in enumerate(reports[0]['data']):
        t += "\\phantom{xxx}&" 
        #t += "&" 
        if len(sideindex) > 1:
            t += "\\multicolumn{%d}{c}{%s}" %(len(sideindex),row['instance']) 
        else:
            t += row['instance'] 
        if r == len(reports[0]['data'])-1:
            t += "\\\\\n"
        else:
            t += " & "

    #Rules
    midrule = 3
    for r,row in enumerate(reports[0]['data']):
        t += "\cmidrule{%d-%d} " % (midrule,midrule+len(sideindex)-1) 
        midrule += len(sideindex)+1
    t+= "\n"

    #Captions
    if len(sideindex)>1:
        t += HEADER_OF_COMPUTED_TABLE + " & "
        for r,row in enumerate(reports[0]['data']):
            t += " & " #fake column
            for i in sideindex:
                t += ABBREV[i]  
                if r == len(reports[0]['data'])-1 and i == sideindex[-1]:
                    t += "\\\\\n"
                else:
                    t += " & "
        t += "\\noalign{\\smallskip}\\hline\\noalign{\\smallskip}\n"                  

    #Imprime os dados
    for jj,report in enumerate(reports):
        print "Compilando",jj,"de",len(reports)
        t += idToName3(report) + " & "
        for r,row in enumerate(reports[0]['data']):
            row = report['data'][r]
            t += " & " #fake column
            for i in sideindex:
                key = FIELDS[i]
                value = row[FIELDS[i]] 
                latexValue = ""
                if value == None:
                    latexValue = " - "
                else:
                    if TYPES[i] in ("float","int"):
                        value = math.fabs(value)
                        mask = '0'
                        if TYPES[i] == "float":
                            mask = '0.01' if DISPLAY[i] == "" else DISPLAY[i] 
                        maskedValue = Decimal(value).quantize(Decimal(mask))
                        latexValue = '{:,}'.format(maskedValue)
                        if len(BESTOBJ[i])>0:
                            direction = eval(BESTOBJ[i])
                            best = direction([Decimal(rep["data"][r][key]).quantize(Decimal(mask)) for rep in reports]) 
                            if r==0:
                               report['rank'][key] = 0
                            if maskedValue==best:
                               latexValue = bold(latexValue)
                               report['rank'][key] = report['rank'][key]+1;
                    else:
                        latexValue = str(value)


                t += latexValue

                if r == len(reports[0]['data'])-1 and i == sideindex[-1]:
                    t += "\\\\\n"
                else:
                    t += " & "
    #t += "\\noalign{\\smallskip}\\hline\n"                  
    t += "\\noalign{\\smallskip}\n"                  
    #Imprime a média.. ########################################################33
    #t += "Avg. & "
    """
    for report in reports:
        row = report['computed']['mid']
        t += " & " #fake column
        for i in sideindex:
            key = FIELDS[i]
            value = row[key] 
            latexValue = ""
            if value == None:
                latexValue = " - "
            else:
                if TYPES[i] in ("float","int"):
                    mask = '0'
                    if TYPES[i] == "float":
                        mask = '0.01' if DISPLAY[i] == "" else DISPLAY[i] 
                    maskedValue = Decimal(value).quantize(Decimal(mask))
                    latexValue = '{:,}'.format(maskedValue)
                    if len(BESTOBJ[i])>0:
                        direction = eval(BESTOBJ[i])
                        best = direction([Decimal(rep["computed"]['mid'][key]).quantize(Decimal(mask)) for rep in reports]) 
                        if maskedValue==best:
                            latexValue = bold(latexValue)
                else:
                    latexValue = str(value)


            t += latexValue

            if report == reports[-1] and i == sideindex[-1]:
                t += "\\\\\n"
            else:
                t += " & "
    
    #RANK ------------------------------------------------------------------------------
    t += "Best(\\%) & "
    for report in reports:
        row = report['rank']
        t += " & " #fake column
        for i in sideindex:
            key = FIELDS[i]
            latexValue = " - " 
            if len(BESTOBJ[i])>0:
                value = row[key] 
                perc = Decimal(float(value)/len(report['data'])*100.0).quantize(Decimal("0")) 
                latexValue = str(perc)  
                best = max([rep["rank"][key] for rep in reports]) 
                if value==best:
                    latexValue = bold(latexValue)

            t += latexValue

            if report == reports[-1] and i == sideindex[-1]:
                t += "\\\\\n"
            else:
                t += " & "
    """
    #t += "\\noalign{\\smallskip}\\hline\n"                  
    t += "\\end{tabular}\n"                  
    #t += "\\labelcaption{tab:%s-%s}{%s}\n" % (TESTID,report["id"],report["description"])                  
    t += "\\end{table*}"
    return t

#Cria uma tabela com dados de vários relatórios lado a lado.
def create_side_table(description):
    t = ""
    t += "\\caption{%s}\n" % description                  
    t += "\\medskip\n"
    t += "\\label{tab:%s-%s}\n" % (TESTID,"sidetable")                  
    t += "\\centering\n"
    t += "\\tiny" + "\n"

    #Ajuste do alinhamento
    t += "\\begin{tabular}{@{}r"
    for r in reports:
        t+= "@{}c@{}" #fake column
        for i in sideindex:
            t += ("r" if TYPES[i] in ("int","float") else "c") 
            if i != sideindex[-1]:
               t += "@{\\ \\ }" #Espaçamento entre colunas
            if i == sideindex[-1] and r == reports[-1]:
               t += "@{}"
    t += "}\n"
    t += "\\hline\\noalign{\\smallskip}\n"

    #Captions of group
    t+= "& "
    for r in reports:
        t += "\\phantom{x}&" 
        #t += "&" 
        if len(sideindex) > 1:
            t += "\\multicolumn{%d}{c}{%s}" %(len(sideindex),idToName(r)) 
        else:
            t += idToName(r)
        if r == reports[-1]:
            t += "\\\\\n"
        else:
            t += " & "

    #Captions of group
    midrule = 3
    for r in reports:
        t += "\cmidrule{%d-%d} " % (midrule,midrule+len(sideindex)-1) 
        midrule += len(sideindex)+1
    t+= "\n"

    #Captions
    if len(sideindex)>1:
        t += COLS['instance']['abbrev'] + " & "
        for r in reports:
            t += " & " #fake column
            for i in sideindex:
                t += ABBREV[i]  
                if r == reports[-1] and i == sideindex[-1]:
                    t += "\\\\\n"
                else:
                    t += " & "
        t += "\\noalign{\\smallskip}\\hline\\noalign{\\smallskip}\n"                  

    #Imprime os dados
    for r,row in enumerate(reports[0]['data']):
        t += row['instance'] + " & "
        for report in reports:
            row = report['data'][r]
            t += " & " #fake column
            for i in sideindex:
                key = FIELDS[i]
                value = row[FIELDS[i]] 
                latexValue = ""
                if value == None:
                    latexValue = " - "
                else:
                    if TYPES[i] in ("float","int"):
                        value = math.fabs(value)
                        mask = '0'
                        if TYPES[i] == "float":
                            mask = '0.01' if DISPLAY[i] == "" else DISPLAY[i] 
                        maskedValue = Decimal(value).quantize(Decimal(mask))
                        latexValue = '{:,}'.format(maskedValue)
                        if len(BESTOBJ[i])>0:
                            direction = eval(BESTOBJ[i])
                            best = direction([Decimal(rep["data"][r][key]).quantize(Decimal(mask)) for rep in reports]) 
                            if r==0:
                               report['rank'][key] = 0
                            if maskedValue==best:
                               latexValue = bold(latexValue)
                               report['rank'][key] = report['rank'][key]+1;
                    else:
                        latexValue = str(value)


                t += latexValue

                if report == reports[-1] and i == sideindex[-1]:
                    t += "\\\\\n"
                else:
                    t += " & "
    #t += "\\noalign{\\smallskip}\\hline\n"                  
    t += "\\noalign{\\smallskip}\n"                  
    #Imprime a média.. ########################################################33
    t += "Avg. & "
    for report in reports:
        row = report['computed']['mid']
        t += " & " #fake column
        for i in sideindex:
            key = FIELDS[i]
            value = row[key] 
            latexValue = ""
            if value == None:
                latexValue = " - "
            else:
                if TYPES[i] in ("float","int"):
                    mask = '0'
                    if TYPES[i] == "float":
                        mask = '0.01' if DISPLAY[i] == "" else DISPLAY[i] 
                    maskedValue = Decimal(value).quantize(Decimal(mask))
                    latexValue = '{:,}'.format(maskedValue)
                    if len(BESTOBJ[i])>0:
                        direction = eval(BESTOBJ[i])
                        best = direction([Decimal(rep["computed"]['mid'][key]).quantize(Decimal(mask)) for rep in reports]) 
                        if maskedValue==best:
                            latexValue = bold(latexValue)
                else:
                    latexValue = str(value)


            t += latexValue

            if report == reports[-1] and i == sideindex[-1]:
                t += "\\\\\n"
            else:
                t += " & "
    #RANK ------------------------------------------------------------------------------
    t += "Best(\\%) & "
    for report in reports:
        row = report['rank']
        t += " & " #fake column
        for i in sideindex:
            key = FIELDS[i]
            latexValue = " - " 
            if len(BESTOBJ[i])>0:
                value = row[key] 
                perc = Decimal(float(value)/len(report['data'])*100.0).quantize(Decimal("0")) 
                latexValue = str(perc)  
                best = max([rep["rank"][key] for rep in reports]) 
                if value==best:
                    latexValue = bold(latexValue)

            t += latexValue

            if report == reports[-1] and i == sideindex[-1]:
                t += "\\\\\n"
            else:
                t += " & "
    t += "\\noalign{\\smallskip}\\hline\n"                  
    t += "\\end{tabular}\n"                  
    #t += "\\labelcaption{tab:%s-%s}{%s}\n" % (TESTID,report["id"],report["description"])                  
    return t

#Analisa os dados de um relatório e cria uma tabela simples em latex
def create_single_table(report):

    t  = "\\begin{table}[H]\n"
    t += "\\caption{%s}\n" % report["description"]                  
    t += "\\label{tab:%s-%s}\n" % (TESTID,report["id"])                  
    t += "\\centering\n"
    t += FONTSIZE + "\n"
    #Ajuste do alinhamento
    t += "\\begin{tabular}{"
    for i in findex:
        t += ("r" if TYPES[i] in ("int","float") else "c") 
    t += "}\n"
    t += "\\hline\\noalign{\\smallskip}\n"
    for i in findex:
        t += ABBREV[i]  
        if i == findex[-1]:
            t += "\\\\\n"
        else:
            t += " & "
    t += "\\noalign{\\smallskip}\\hline\\noalign{\\smallskip}\n"                  

    #Imprime os dados
    for r,row in enumerate(report['data']):
        for i in findex:
            key = FIELDS[i]
            value = row[FIELDS[i]] 
            latexValue = ""
            if value == None:
                latexValue = " - "
            else:
                if TYPES[i] == "float":
                    mask = '0.01' if DISPLAY[i] == "" else DISPLAY[i] 
                    latexValue = '{:,}'.format(Decimal(value).quantize(Decimal(mask)))
                else:
                    latexValue = str(value)
            # TODO: Deixar igual ao cálculo da sidetable
            #if len(BESTOBJ[i])>0:
            #    if value==report['computed'][BESTOBJ[i]][key]:
            #        latexValue = bold(latexValue)

            t += latexValue

            if i == findex[-1]:
                t += "\\\\\n"
            else:
                t += " & "
    #t += "\\noalign{\\smallskip}\\hline\n"                  
    t += "\\noalign{\\smallskip}\n"                  
    #Imprime a média.. 
    row = report['computed']['mid']
    for i in findex:
        key = FIELDS[i]
        value = row[key] 
        if value == None:
            t += " - "
        else:
            latexValue = ""
            if TYPES[i] == "float":
                mask = '0.01' if DISPLAY[i] == "" else DISPLAY[i] 
                latexValue = str(Decimal(value).quantize(Decimal(mask)))
            else:
                latexValue = str(value)


            t += latexValue

        if i == findex[-1]:
            t += "\\\\\n"
        else:
            t += " & "
    t += "\\noalign{\\smallskip}\\hline\n"                  
    t += "\\end{tabular}\n"                  
    #t += "\\labelcaption{tab:%s-%s}{%s}\n" % (TESTID,report["id"],report["description"])                  
    t += "\\end{table}\n"
    return t

#Cria um arquivo plano com dados cmoputados 
def create_computed_plain_file(func,sortBy="obj",idWrapper="idToName3"):

    reports_sorted = sorted(reports, key=lambda k: k['computed'][func][sortBy]) 

    t = ""

    #Imprime os dados
    for report in reports_sorted:
        row = report['computed'][func]
        for i in findex:
            if FIELDS[i] == 'instance':
                t += eval(idWrapper+"(report)")
            else:
                value = row[FIELDS[i]] 
                if value == None:
                    t += " - "
                else:
                    if TYPES[i] == "float":
                        mask = '0.01' if DISPLAY[i] == "" else DISPLAY[i] 
                        t += str(Decimal(value).quantize(Decimal(mask)))
                    else:
                        t += str(value)

            if i == findex[-1]:
                t += "\n"
            else:
                t += " "
    return t

#Cria uma tabela com um dado computado func para os relatórios
def create_computed_table(caption, func, sortBy="obj"):

    t = FONTSIZE + "\n"
    #Ajuste do alinhamento
    t += "\\begin{longtable}{"
    for i in findex:
        t += ("r" if TYPES[i] in ("int","float") else "l") 
    t += "}\n"
    #t += "\\caption{%s}\n" % caption                  
    #t += "\\label{tab:%s-%s}\n" % (TESTID,func)                  
    #t += "\\centering\n"

    t += "\\hline\n"
    for i in findex:
        if FIELDS[i] == 'instance':
            t += HEADER_OF_COMPUTED_TABLE 
        else:
            t += ABBREV[i]  
        if i == findex[-1]:
            t += "\\\\\n"
        else:
            t += " & "
    t += "\\hline\n"                  

    reports_sorted = sorted(reports, key=lambda k: k['computed'][func][sortBy]) 

    #Imprime os dados
    for report in reports_sorted:
        row = report['computed'][func]
        for i in findex:
            if FIELDS[i] == 'instance':
                t += idToName3(report) 
            else:
                value = row[FIELDS[i]] 
                if value == None:
                    t += " - "
                else:
                    if TYPES[i] == "float":
                        mask = '0.01' if DISPLAY[i] == "" else DISPLAY[i] 
                        t += str(Decimal(value).quantize(Decimal(mask)))
                    else:
                        t += str(value)

            if i == findex[-1]:
                t += "\\\\\n"
            else:
                t += " & "
    t += "\\hline\n"                  
    t += "\\end{longtable}\n"                  
    return t
# Le um arquivo report e retorna um dicionário contendo
# os headers e os dados indexados por campo
def read_report(reportFile):
    f = open(reportFile,'r')
    lines = f.readlines()
    f.close()

    #leitura dos headers do relatório
    headers = {} 
    for i,line in enumerate(lines):
        line = line[0:-1]
        if line.strip()=="":
            lines = lines[i+1:]
            break
        (key,value) = line.split("=")
        headers[key.strip().lower()] = value.strip()

    #leitura dos dados do relatório
    data = [] 

    for line in lines:
        line = line[0:-1]
        if line.strip()=="":
            continue
        row = {}
        rawValues = line.split(",")
        for i,raw in enumerate(rawValues):
            if POSPROC[i] != "":
                value = eval(POSPROC[i] % raw.strip());
            else:
                value = eval(TYPES[i]+"(raw.strip())");
            row[FIELDS[i]] = value 
        data.append(row)


    computedData = {}
    mid = {}
    maximun = {}
    minimum = {}
    total = {}

    #Cálculo dos valores computados
    i = 0
    for row in data:
        i = i + 1
        for (key,value) in row.items():
            computed = None
            if isinstance(value,Number):
                computed = value
            
            if i>1:
                if total[key]!=None and computed!=None:
                    total[key] = total[key] + computed
                    mid[key] = total[key]/i
                    maximun[key] = max(maximun[key],computed)
                    minimum[key] = min(minimum[key],computed)
            else:
                total[key] = computed
                mid[key] = computed
                maximun[key] = computed
                minimum[key] = computed

    computedData['mid'] = mid 
    computedData['sum'] = total 
    computedData['min'] = minimum 
    computedData['max'] = maximun 

    headers["data"] = data
    headers["computed"] = computedData
    headers["rank"] = {} #Usado mais pra frente
    return headers

def idToName2(report):
    name = ""
    id = report['id']
    """ Funçao usada para criar um nome curto a partir de um header """

    if id.find("class")>0:
        name += "C"
    if id.find("teacher")>0:
        name += "T"
    if id.find("day")>0:
        name += "D"

    if id.find("FIR0")>0:
        name += "_0~"
    else:
        name += "_1~"

    if id.find("combine")>0:
        name += "com"
    if id.find("divide")>0:
        name += "spl"
    if id.find("cover")>0:
        name += "cov"
    if id.find("mix")>0:
        name += "mix"

    name += "_{%s}" % id[-3:].replace("-",",")

    name = "$%s$" % (name)
    return name




HEADER_OF_COMPUTED_TABLE = "$D~~~F~~~~k_1-k_2~~~~STL $"

def idToName3(report):
    name = ""
    id = report['id']
    return id[14:];
    #return id
    """ Funçao usada para criar um nome curto a partir de um header """

    if id.find("class")>0:
        name += "C"
    if id.find("teacher")>0:
        name += "T"
    if id.find("day")>0:
        name += "D"


    if id.find("FIR0")>0:
        name += "~~~0~~"
    else:
        name += "~~~1~~"

    if id.find("combine")>0:
        name += ""
    if id.find("divide")>0:
        name += "spl"
    if id.find("cover")>0:
        name += "cov"
    if id.find("mix")>0:
        name += "mix"


    name += "~~~~"
    if id.endswith("10-10"):
        name += "10-10"
        name += "~~~"
    elif id.endswith("11-11"):
        name += "11-11"
        name += "~~~"
    elif id.endswith("12-12"):
        name += "12-12"
        name += "~~~"
    else:
        name += id[-3:]
        name += "~~~~~~~"

    if id.find("N30")>0:
        name += "30"
    else:
        name += "~\infty"

    name = "$%s$" % (name)
    return name

def idToNamePlain(report):
    name = ""
    id = report['id']

    if id.find("class")>0:
        name += "C"
    if id.find("teacher")>0:
        name += "T"
    if id.find("day")>0:
        name += "D"

    name += " "

    if id.find("FIR0")>0:
        name += "0"
    else:
        name += "1"

    name += " "

    if id.find("N30")>0:
        name += "30"
    else:
        name += "999999"

    name += " "

    if id.endswith("10-10"):
        name += "10 10"
    elif id.endswith("11-11"):
        name += "11 11"
    elif id.endswith("12-12"):
        name += "12 12"
    else:
        name += id[-3:].replace("-"," ")

    return name

def idToName(report):
    name = "\stackrel"
    id = report['id']
    """ Funçao usada para criar um nome curto a partir de um header """

    if id.find("combine")>0:
        name += "{comb}"
    if id.find("divide")>0:
        name += "{spli}"
    if id.find("cover")>0:
        name += "{cov}"
    if id.find("mix")>0:
        name += "{mix}"

    dec = "\stackrel"

    dec += "{%s}" % id[-3:].replace("-",",")

    if id.find("class")>0:
        dec += "{C}"
    if id.find("teacher")>0:
        dec += "{T}"
    if id.find("day")>0:
        dec += "{D}"
    
    name = "$%s{%s}$" % (name,dec)
    return name



def fixinst(s):
    """ Função usada para formatar o nome da instância """
    return os.path.basename(s.split("--")[1]).split(".")[0][-1]


if __name__ == "__main__":
    COLS     = {}

    FIELDS   = ['instance'      ,'obj'      ,'time'   ,'first-time'                             ,'last-time','inf','nf' ,'tl' ,'opt','imp','iter' , 'avgnodetime', 'maxnodetime', 'sumpartitionsize', 'avgpartitionsize' ]#,'gap'  ]
    TYPES    = ['str'           ,'float'    ,'float'  ,'float'                                  ,'float'    ,'int','int','int','int','int','int'  , 'float'      , 'float'      , 'int'             , 'float'            ]#,'float']
    BESTOBJ  = [''              ,'min'      ,'min'    ,'min'                                    ,'min'      ,'min','min','min','min','min','min'  , 'min'        , 'min'        , 'min'             , 'min'              ]#,'min'  ]
    POSPROC  = ['fixinst("%s")' ,''         ,''       ,''                                       ,''         ,''   ,''   ,''   ,''   ,''   ,''     , ''           , ''           , ''                , ''                 ]#,''     ]
    DISPLAY  = [''              ,'0'        ,'0.1'    ,'0.1'                                    ,'0.1'      ,'0'  ,'0'  ,'0'  ,'0'  ,'0'  ,'0'    , '0.01'       , '0.01'       , '0'               , '1'             ]#,'0.1'  ]
    CAPTIONS = ['Instance'      ,'Objective','Runtime','Spent time to reach a feasible solution','Last. Sol','Inf','NF' ,'TL' ,'Opt','Imp','Iter' , ''           , ''           , ''                , ''                 ]#,'Gap'  ]
    ABBREV   = ['inst'          ,'obj'      ,'time'   ,'$t_0$ (s)'                              ,'$t^*$(s)'  ,'inf','nf' ,'tl' ,'opt','imp','iter','avg.node(s)' , 'max.node(s)', 'sumPartitionSize', 'avg.vars' ]#,'Gap'  ]    

    for i,f in enumerate(FIELDS):
        COLS[f] = {}
        COLS[f]['type'] = TYPES[i]
        COLS[f]['caption'] = CAPTIONS[i]
        COLS[f]['abbrev'] = ABBREV[i]

    parser = OptionParser()
    parser.add_option("-f","--fields",dest="fields",help="Nome dos campos separados por vírgula",default="instance,obj,time",type="string")
    parser.add_option("--sidefields",dest="sidefields",help="Nome dos campos da tabela side separados por vírgula",default="obj",type="string")
    parser.add_option("--sortfield",dest="sortfield",help="Campo escolhido para ordenar os dados",default="obj",type="string")
    parser.add_option("-s","--size",dest="size",help="Tamanho da fonte para gerar as tabelas",default="normalsize",type="string")
    parser.add_option("-g","--graph",action="store_true",dest="graph",help="Ativa geração de gráficos")    
    parser.add_option("-o","--output",dest="output",help="Nome do arquivo tex a ser gerado",default=None,type="string")
    parser.add_option("--computedfile",dest="computedfile",help="Nome do arquivo tex para gerar dados computados",default=None,type="string")
    parser.add_option("--plainfile",dest="plainfile",help="Nome do arquivo para gerar média em texto plano",default=None,type="string")
    parser.add_option("--sidefile",dest="sidefile",help="Tabela serão adicionadas no final desse arquivo",default=None,type="string")
    parser.add_option("-e","--encoding",dest="encoding",help="Codificação do arquivo gerado.",default="latin-1",type="string")
    parser.add_option("-i","--id",dest="id",help="Identificar do teste",default="",type="string")
    parser.add_option("-d","--description",dest="description",help="Descrição do teste",default="",type="string")

    (opts, args) = parser.parse_args()

    #Diretório onde serão colocados os arquivos temporários 
    TESTID = opts.id
    RESDIR = opts.id
    FONTSIZE = "\\" + opts.size
    if RESDIR.strip()!="":
        RESDIR+="/"
    if opts.output == None:
        OUTDIR=""
    else:
        OUTDIR = os.path.dirname(opts.output)
    if OUTDIR=="":
        OUTDIR="."
    OUTDIR+="/"

    if len(args)==0:
        print "É necessário informar ao menos um arquivo de dados."
        sys.exit(1)


    fields = [] #Campos selecionados
    findex = [] #índice do campo nos dados

    if len(opts.fields.strip())>0:
        for f in opts.fields.split(","):
            f = f.strip().lower()
            try:
                index = FIELDS.index(f)
                fields.append(f)
                findex.append(index)
            except:
                print "(W) fields: O campo '%s' não existe nos dados do relatório." % f

    if len(fields)==0:
        fields = FIELDS
        findex = range(len(FIELDS))

    sideindex = [] 

    if len(opts.sidefields.strip())>0:
        for f in opts.sidefields.split(","):
            f = f.strip().lower()
            try:
                index = FIELDS.index(f)
                sideindex.append(index)
            except:
                print "(W) sidefields: O campo '%s' não existe nos dados do relatório." % f

    reports = []
    for r in args:
        report = read_report(r)
        reports.append(report)
    #pprint.pprint(reports[0],indent=4)

    #Cria tabela com algum atributo computado
    if opts.computedfile!=None:
        sfile = open(opts.computedfile,"a") #Open file for append table
        sfile.write(create_computed_table('Average results','mid',opts.sortfield))
        sfile.close()
        print "Tabela com as médias gravada em '%s'." % opts.computedfile 
    #Cria tabela com algum atributo computado
    if opts.plainfile!=None:
        sfile = open(opts.plainfile,"a") #Open file for append table
        sfile.write(create_computed_plain_file('mid',opts.sortfield,"idToNamePlain"))
        sfile.close()
        print "Arquivo plano com as médias gravada em '%s'." % opts.plainfile 

    #Cria side table 
    if opts.sidefile!=None:
        sfile = open(opts.sidefile,"a") #Open file for append table
        sfile.write(create_side_table2(opts.description))
        sfile.close()
        print "Sidetable gravada em '%s'." % opts.sidefile 

    #Cria tabelas simples
    if opts.output!=None:
        tex = "" 
        for report in reports:
            t = create_single_table(report)
            tex += t
            tex += "\\vspace{-0.8cm}\n"
            tex += "\n"
        f = open(opts.output,'a')
        f.write(unicode(tex,'utf-8').encode(opts.encoding))
        f.close()
        print "Tabelas simples gravadas em '%s'." % opts.output 

    #Cria gráficos comparativos por campo
    if opts.graph and len(reports) > 0:
        tex = ""
        for f in fields:
            t = create_histrogram_graf(f) 
            tex += t + "\n"
        f = open(opts.output,'a')
        f.write(unicode(tex,'utf-8').encode(opts.encoding))
        f.close()
        print "Gráficos gravados em '%s'." % opts.output 

    


